import sim.engine.*;
import sim.util.Bag;
import sim.util.Int2D;

public class Cop extends Agent implements Steppable{
	private static final long serialVersionUID = 1L;

	public Cop(Int2D loc) {
		super(loc);
	}
	
	public void step(SimState state){
		EpsteinGrid reb = (EpsteinGrid)state;
		reb.grid.getNeighborsMaxDistance(loc.x, loc.y, reb.copVision, false, neighborsX, neighborsY);
		
		move(reb);
		arrestSuspect(reb);
	}
	
	private void arrestSuspect(EpsteinGrid epState) {
		Bag suspects = new Bag(); //bag of suspects for arrest
		
		//Loop through all agents within vision
		for(int i = 0; i < neighborsX.size(); i++){
			int x = neighborsX.get(i);
			int y = neighborsY.get(i);
			
			Bag agents = epState.grid.getObjectsAtLocation(x, y);
			
			//if there is an active agent in this location, add them to the bag of suspects.
			if(agents != null){
				Agent agent;
				for(int j = 0; j < agents.size(); j++){
					agent = (Agent)agents.get(j);
					
					if(agent.active){
						suspects.add(agent);
					}
				}
			}
		}
		
		/*If any active agents have been added to the bag of suspects,
		one is selected randomly and jailed for a random period of time (0 - maxJailTerm).  
		The cop then moves to the location of the suspect.*/
		if(suspects.size() > 0){
			Agent agent = (Agent) suspects.get(epState.random.nextInt(suspects.size()));
			
			agent.active = false;
			agent.jailTerm = epState.random.nextInt(epState.maxJailTerm);
			
			loc = new Int2D(agent.loc.x, agent.loc.y);				
			epState.grid.setObjectLocation(this, loc);
			
			epState.activeCount--;
			
			//if the random jail term is 0, only increase quiet count.
			if(agent.jailTerm > 0)
				epState.jailCount++;
			else
				epState.quietCount++;
		}
	}
}
